﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Game1942.Library.Background.Bodies
{
    public abstract class Body
    {
        protected List<ReferencePoint> bodyList;
   
        protected Body ()
        {
            bodyList = new List<ReferencePoint>();
        }

        public abstract void CreateBodyOf(Element anOwner);

        // Delete if unused
        public List<ReferencePoint> GetBody()
        {
            return bodyList;
        }

		// Move the body relative to another body
		// By adding to the position of the body, the one of the passed point
        public void RelativeMove(Point aPoint)
        {
            if (bodyList == null)
            {
                throw new InvalidOperationException("The relative move of a body can be done after the body was created");
            }
            foreach (var point in bodyList)
            {
                point.Plus(aPoint);
            }
        }

		// Locate the object, with its points, in the map
        public bool Locate()
        {
            Background myMap = Background.Instance;
            foreach (var refPoint in bodyList)
            {
                // This method throws exceptions if it can't deliver
                // These exceptions are meant to be handled by the Position class
                if (!myMap.IsNullAt(refPoint))
                {
                    return false;
                }
                myMap.PutPoint(refPoint);

            }
            return true;
        }

		// Remove the body and all its points from the map
        public void DeleteFromMap()
        {
            var map = Background.Instance;
            foreach (var point in bodyList)
            {
                map.Matrix[point.X, point.Y] = null;
            }
        }

        public abstract bool BelongsTo(Background map);   //Check if the body belongs to the map
        

		// Explicit "Destructor"
		// To be used when we tried to locate a body in the map and run into problems
		// Removes all points that belong to the body 
        public void Clean()
        {
			// Find the body in the map
            var myMap = Background.Instance;
            if (bodyList==null)
            {
                throw new NullReferenceException("'bodyList' has not been initialized.");
            }
            var owner = bodyList[0].Owner;
            
            foreach (var point in bodyList)
            {
                if (!point.BelongsTo(myMap) || ReferenceEquals(myMap.Matrix[point.X, point.Y],null))
                {
                    break;
                }
                if (myMap.Matrix[point.X, point.Y].Owner != owner)
                {
                    break;
                }
                myMap.Matrix[point.X, point.Y] = null;
            }
			
        }

        public abstract Point GetBodyDimension();
    }
}
